package com.shop.cereshop.app.service.cart.impl;

import com.shop.cereshop.app.dao.cart.CereShopCartDAO;
import com.shop.cereshop.app.dao.product.CereProductSkuDAO;
import com.shop.cereshop.app.domain.activity.ActivityData;
import com.shop.cereshop.app.page.cart.CartSku;
import com.shop.cereshop.app.page.cart.ShopCart;
import com.shop.cereshop.app.param.cart.*;
import com.shop.cereshop.app.redis.service.api.StringRedisService;
import com.shop.cereshop.app.service.cart.CereCartAttributeService;
import com.shop.cereshop.app.service.cart.CereShopCartService;
import com.shop.cereshop.app.service.discount.CereShopDiscountDetailService;
import com.shop.cereshop.app.service.discount.CereShopDiscountService;
import com.shop.cereshop.app.service.groupwork.CereShopGroupWorkDetailService;
import com.shop.cereshop.app.service.log.CerePlatformLogService;
import com.shop.cereshop.app.service.seckill.CereShopSeckillDetailService;
import com.shop.cereshop.app.service.seckill.CereShopSeckillService;
import com.shop.cereshop.app.service.shop.CereShopConversionService;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.constant.ParamEnum;
import com.shop.cereshop.commons.domain.buyer.CereBuyerUser;
import com.shop.cereshop.commons.domain.cart.CereCartAttribute;
import com.shop.cereshop.commons.domain.cart.CereShopCart;
import com.shop.cereshop.commons.domain.product.CereProductSku;
import com.shop.cereshop.commons.domain.shop.CereShopConversion;
import com.shop.cereshop.commons.domain.tool.CereShopDiscount;
import com.shop.cereshop.commons.domain.tool.CereShopSeckill;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.utils.EmptyUtils;
import com.shop.cereshop.commons.utils.TimeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class CereShopCartServiceImpl implements CereShopCartService {

    @Autowired
    private CereShopCartDAO cereShopCartDAO;

    @Autowired
    private CereCartAttributeService cereCartAttributeService;

    @Autowired
    private CereShopConversionService cereShopConversionService;

    @Autowired
    private CerePlatformLogService cerePlatformLogService;

    @Autowired
    private CereShopGroupWorkDetailService cereShopGroupWorkDetailService;

    @Autowired
    private CereShopSeckillDetailService cereShopSeckillDetailService;

    @Autowired
    private CereProductSkuDAO cereProductSkuDao;

    @Autowired
    private CereShopDiscountDetailService cereShopDiscountDetailService;

    @Autowired
    private CereShopSeckillService cereShopSeckillService;

    @Autowired
    private CereShopDiscountService cereShopDiscountService;

    @Autowired
    private StringRedisService stringRedisService;

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void addCart(AddCartParam param, CereBuyerUser user) throws CoBusinessException {
        String time = TimeUtils.yyMMddHHmmss();
        //查询活动价格
        ActivityData data = cereShopCartDAO.findActivityData(param.getSkuId());
        //查询购物车中是否已存在该商品
        CereShopCart shopCart = cereShopCartDAO.findShopCart(user.getBuyerUserId(), param.getSkuId());
        if (shopCart != null) {
            //查询sku中的值
            CereProductSku cereProductSku = cereProductSkuDao.selectByPrimaryKey(param.getSkuId());
            //在原有数据基础上加上数量
            shopCart.setNumber(shopCart.getNumber() + param.getNumber());
            if(shopCart.getNumber() > cereProductSku.getStockNumber()){
                throw new CoBusinessException(CoReturnFormat.EXCEED_INVENTORY);
            }
            shopCart.setUpdateTime(time);
            if (data != null) {
                //校验活动商品限量和限购
                checkActivity(data, shopCart);
                //更新活动价格
                shopCart.setProductPrice(data.getPrice());
            }
            cereShopCartDAO.updateByPrimaryKeySelective(shopCart);
        } else {
            //新增购物车商品数据
            shopCart = cereShopCartDAO.findSku(param.getSkuId());
            shopCart.setCreateTime(time);
            shopCart.setBuyerUserId(user.getBuyerUserId());
            shopCart.setNumber(param.getNumber());
            if (data != null) {
                //校验活动商品限量和限购
                checkActivity(data, shopCart);
                //更新活动价格
                shopCart.setProductPrice(data.getPrice());
            }
            cereShopCartDAO.insert(shopCart);
            //查询规格属性值数据同步到购物车商品规格明细表中
            List<CereCartAttribute> attributes = cereShopCartDAO.findAttributes(param.getSkuId());
            if (attributes != null) {
                CereShopCart finalShopCart = shopCart;
                attributes.forEach(a -> a.setCartId(finalShopCart.getCartId()));
                cereCartAttributeService.insertBatch(attributes);
            }
        }
        //新增转化数据
        CereShopConversion cereShopConversion = new CereShopConversion();
        cereShopConversion.setShopId(shopCart.getShopId());
        cereShopConversion.setCreateTime(time);
        cereShopConversion.setType(ParamEnum.CONVERSION_CART.getCode());
        cereShopConversionService.insert(cereShopConversion);
        //新增日志
        cerePlatformLogService.addLog(user, "购物车模块", "客户端操作", "加入购物车", user.getBuyerUserId(), time);
    }

    private void checkActivity(ActivityData data, CereShopCart shopCart) throws CoBusinessException {
        if (!EmptyUtils.isEmpty(data.getShopSeckillId())) {
            //秒杀活动校验,查询秒杀活动数据
            CereShopSeckill cereShopSeckill = cereShopSeckillService.findById(data.getShopSeckillId());
            if (cereShopSeckill != null) {
                if (IntegerEnum.PRODUCT_IF_LIMIT_YES.getCode().equals(cereShopSeckill.getIfLimit())) {
                    //如果秒杀活动限购,校验数量
                    if (shopCart.getNumber() > cereShopSeckill.getLimitNumber()) {
                        throw new CoBusinessException(CoReturnFormat.PRODUCT_LIMIT_ERROR);
                    }
                }
                if (IntegerEnum.YES.getCode().equals(cereShopSeckill.getIfNumber())) {
                    int surplusNumber = 0;
                    //如果限量,查询缓存中活动商品仅剩数量
                    if (EmptyUtils.isEmpty(stringRedisService.get("秒杀活动商品仅剩件数" + cereShopSeckill.getShopSeckillId() + shopCart.getSkuId()))) {
                        //如果没有,取数据库限量库存数据
                        surplusNumber = cereShopSeckillDetailService.findNumber(cereShopSeckill.getShopSeckillId(), shopCart.getSkuId());
                    } else {
                        //如果有,取缓存
                        surplusNumber = (int) stringRedisService.get("秒杀活动商品仅剩件数" + cereShopSeckill.getShopSeckillId() + shopCart.getSkuId());
                    }
                    //判断数量是否大于当前购买数量
                    if (shopCart.getNumber() > surplusNumber) {
                        throw new CoBusinessException(CoReturnFormat.PRODUCT_ALREADY_SELL_OUT);
                    }
                }
            }
        } else if (!EmptyUtils.isEmpty(data.getShopDiscountId())) {
            //限时折扣活动校验,查询限时折扣活动数据
            CereShopDiscount cereShopDiscount = cereShopDiscountService.findById(data.getShopDiscountId());
            if (cereShopDiscount != null) {
                if (IntegerEnum.PRODUCT_IF_LIMIT_YES.getCode().equals(cereShopDiscount.getIfLimit())) {
                    //如果限时折扣活动限购,校验数量
                    if (shopCart.getNumber() > cereShopDiscount.getLimitNumber()) {
                        throw new CoBusinessException(CoReturnFormat.PRODUCT_LIMIT_ERROR);
                    }
                }
                if (IntegerEnum.YES.getCode().equals(cereShopDiscount.getIfNumber())) {
                    int surplusNumber = 0;
                    //如果限量,查询缓存中活动商品仅剩数量
                    if (EmptyUtils.isEmpty(stringRedisService.get("限时折扣活动商品仅剩件数" + cereShopDiscount.getShopDiscountId() + shopCart.getSkuId()))) {
                        //如果没有,取数据库限量库存数据
                        surplusNumber = cereShopDiscountDetailService.findNumber(cereShopDiscount.getShopDiscountId(), shopCart.getSkuId());
                    } else {
                        //如果有,取缓存
                        surplusNumber = (int) stringRedisService.get("限时折扣活动商品仅剩件数" + cereShopDiscount.getShopDiscountId() + shopCart.getSkuId());
                    }
                    //判断数量是否大于当前购买数量
                    if (shopCart.getNumber() > surplusNumber) {
                        throw new CoBusinessException(CoReturnFormat.PRODUCT_ALREADY_SELL_OUT);
                    }
                }
            }
        }
    }

    @Override
    public List<ShopCart> getCart(Long buyerUserId) throws CoBusinessException {
        //查询当前用户购物车店铺数据
        List<ShopCart> shopCarts = cereShopCartDAO.findCartByUserId(buyerUserId);
        if (!EmptyUtils.isEmpty(shopCarts)) {
            //查询商品明细数据
            for (ShopCart shopCart : shopCarts) {
                //根据店铺id查询商品明细
                List<CartSku> cartSkus = cereShopCartDAO.findProductByShopId(shopCart.getShopId(), buyerUserId);
                if (!EmptyUtils.isEmpty(cartSkus)) {
                    for (int i=0;i<cartSkus.size();i++) {
                        List<String> vas = cereShopCartDAO.getBySkuId(cartSkus.get(i).getSkuId());
                        cartSkus.get(i).setValues(vas);
                        String s = vas.toString();
                        cartSkus.get(i).setValue(s.substring(1, s.length()-1));
                    }

                    shopCart.setSkus(cartSkus);
//                    cartSkus.forEach(a -> a.setValues(EmptyUtils.getImages(a.getValue())));
//                    shopCart.setSkus(cartSkus);
                }
            }

        }
//        for (int i=0;i<shopCarts.size();i++){
//            if (shopCarts.get(i).getSkus()==null){
//                shopCarts.remove(i);
//            }
//        }
        if (shopCarts.size() != 0 && shopCarts.get(0).getSkus() == null) {
            shopCarts.remove(0);
        }
        return shopCarts;
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void delete(DeleteParam param, CereBuyerUser user) throws CoBusinessException {
        if (!EmptyUtils.isEmpty(param.getIds())) {
            cereShopCartDAO.deleteByIds(param.getIds(), user.getBuyerUserId());
        }
    }

    @Override
    public void deleteAll(Long buyerUserId) throws CoBusinessException {
        cereShopCartDAO.deleteAll(buyerUserId);
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void selected(SelectedParam param, CereBuyerUser user) throws CoBusinessException {
        List<Long> select = new ArrayList<>();
        List<Long> unSelect = new ArrayList<>();
        //更新购物车选中状态
        if (!EmptyUtils.isEmpty(param.getShopCarts())) {
            param.getShopCarts().forEach(shopCart -> {
                if (!EmptyUtils.isEmpty(shopCart.getSkus())) {
                    shopCart.getSkus().forEach(sku -> {
                        if (IntegerEnum.YES.getCode().equals(sku.getSelected())) {
                            select.add(sku.getSkuId());
                        } else {
                            unSelect.add(sku.getSkuId());
                        }
                    });
                }
            });
            if (!EmptyUtils.isEmpty(select)) {
                //更新选中规格
                cereShopCartDAO.updateSelected(select, user.getBuyerUserId(), IntegerEnum.YES.getCode());
            }
            if (!EmptyUtils.isEmpty(unSelect)) {
                //更新未选中规格
                cereShopCartDAO.updateSelected(unSelect, user.getBuyerUserId(), IntegerEnum.NO.getCode());
            }
        } else {
            //全选
            cereShopCartDAO.updateSelectedAll(user.getBuyerUserId());
        }
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void updateNumber(CartUpdateParam param, CereBuyerUser user) throws CoBusinessException {
        String time = TimeUtils.yyMMddHHmmss();
        //查询活动价格
        ActivityData data = cereShopCartDAO.findActivityData(param.getSkuId());
        //查询购物车商品数据
        CereShopCart shopCart = cereShopCartDAO.findBySkuIdAndUser(param.getSkuId(), user.getBuyerUserId());
        if (shopCart != null) {
            shopCart.setNumber(param.getNumber());
            shopCart.setUpdateTime(time);
            if (data != null) {
                //校验活动限量和限购
                checkActivity(data, shopCart);
            }
            cereShopCartDAO.updateByPrimaryKeySelective(shopCart);
        }
    }

    @Override
    public void deleteSkus(List<CartSku> carts, Long buyerUserId) {
        cereShopCartDAO.deleteSkus(carts, buyerUserId);
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void addBatchCart(BatchCartParam param, CereBuyerUser user) throws CoBusinessException {
        String time = TimeUtils.yyMMddHHmmss();
        if (!EmptyUtils.isEmpty(param.getCarts())) {
            for (AddCartParam cart : param.getCarts()) {
                //查询购物车中是否已存在该商品
                CereShopCart shopCart = cereShopCartDAO.findShopCart(user.getBuyerUserId(), cart.getSkuId());
                if (shopCart != null) {
                    //在原有数据基础上加上数量
                    shopCart.setNumber(shopCart.getNumber() + cart.getNumber());
                    shopCart.setUpdateTime(time);
                    cereShopCartDAO.updateByPrimaryKeySelective(shopCart);
                } else {
                    //新增购物车商品数据
                    shopCart = cereShopCartDAO.findSku(cart.getSkuId());
                    shopCart.setCreateTime(time);
                    shopCart.setBuyerUserId(user.getBuyerUserId());
                    shopCart.setNumber(cart.getNumber());
                    cereShopCartDAO.insert(shopCart);
                    //查询规格属性值数据同步到购物车商品规格明细表中
                    List<CereCartAttribute> attributes = cereShopCartDAO.findAttributes(cart.getSkuId());
                    if (attributes != null) {
                        CereShopCart finalShopCart = shopCart;
                        attributes.forEach(a -> a.setCartId(finalShopCart.getCartId()));
                        cereCartAttributeService.insertBatch(attributes);
                    }
                }
                //新增转化数据
                CereShopConversion cereShopConversion = new CereShopConversion();
                cereShopConversion.setShopId(shopCart.getShopId());
                cereShopConversion.setCreateTime(time);
                cereShopConversion.setType(ParamEnum.CONVERSION_CART.getCode());
                cereShopConversionService.insert(cereShopConversion);
            }
        }
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void buyAgain(BuyerAgainParam param, CereBuyerUser user) throws CoBusinessException {
        String time = TimeUtils.yyMMddHHmmss();
        //根据订单id查询订单商品数据
        List<CartSku> skus = cereShopCartDAO.findOrderProduct(param.getOrderId());
        if (!EmptyUtils.isEmpty(skus)) {
            List<CereShopCart> updates = new ArrayList<>();
            List<CereShopCart> adds = new ArrayList<>();
            skus.forEach(sku -> {
                //查询购物车是否有该商品
                CereShopCart shopCart = cereShopCartDAO.findShopCart(user.getBuyerUserId(), sku.getSkuId());
                if (shopCart != null) {
                    //加上该订单商品数量
                    shopCart.setNumber(shopCart.getNumber() + sku.getNumber());
                    shopCart.setUpdateTime(time);
                    shopCart.setSelected(IntegerEnum.YES.getCode());
                    updates.add(shopCart);
                } else {
                    //新增购物车商品数据
                    shopCart = new CereShopCart();
                    shopCart.setCreateTime(time);
                    shopCart.setBuyerUserId(user.getBuyerUserId());
                    shopCart.setNumber(sku.getNumber());
                    shopCart.setProductId(sku.getProductId());
                    shopCart.setSkuId(sku.getSkuId());
                    shopCart.setSKU(sku.getSKU());
                    shopCart.setImage(sku.getImage());
                    shopCart.setProductPrice(sku.getPrice());
                    shopCart.setWeight(sku.getWeight());
                    shopCart.setSelected(IntegerEnum.NO.getCode());
                    shopCart.setProductName(sku.getProductName());
                    shopCart.setShopId(sku.getShopId());
                    shopCart.setSelected(IntegerEnum.YES.getCode());
                    adds.add(shopCart);
                }
            });
            if (!EmptyUtils.isEmpty(adds)) {
                cereShopCartDAO.insertBatch(adds);
            }
            if (!EmptyUtils.isEmpty(updates)) {
                cereShopCartDAO.updateBatch(updates);
            }
        }
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void updateSku(UpdateSkuParam param, CereBuyerUser user) throws CoBusinessException {
        //根据原来的规格id查询购物车商品数据
        CereShopCart cereShopCart = cereShopCartDAO.findShopCart(user.getBuyerUserId(), param.getSkuId());
        if (cereShopCart != null) {
            //查询修改后的商品数据
            CereShopCart sku = cereShopCartDAO.findSku(param.getNewSkuId());
            if (sku != null) {
                cereShopCart.setSkuId(param.getNewSkuId());
                cereShopCart.setProductId(sku.getProductId());
                cereShopCart.setProductName(sku.getProductName());
                cereShopCart.setProductPrice(sku.getProductPrice());
                cereShopCart.setWeight(sku.getWeight());
                cereShopCart.setSKU(sku.getSKU());
                cereShopCart.setImage(sku.getImage());
                cereShopCart.setNumber(param.getNumber());
                //查询活动价格
                ActivityData data = cereShopGroupWorkDetailService.findPriceBySkuId(param.getNewSkuId());
                if (data == null) {
                    //查询秒杀价格
                    data = cereShopSeckillDetailService.findPriceBySkuId(param.getNewSkuId());
                    if (data == null) {
                        //查询限时折扣价
                        data = cereShopDiscountDetailService.findPriceBySkuId(param.getNewSkuId());
                    }
                }
                if (data != null) {
                    //校验活动限购和限量
                    checkActivity(data, cereShopCart);
                }
                cereShopCartDAO.updateByPrimaryKeySelective(cereShopCart);
            }
        }
    }

    @Override
    public Integer findNumber(Long buyerUserId) {
        return cereShopCartDAO.findNumber(buyerUserId);
    }

    @Override
    public void updateBuyerData(Long buyerUserId, Long id) throws CoBusinessException {
        cereShopCartDAO.updateBuyerData(buyerUserId, id);
    }
}
